package com.woniu.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.woniu.entity.PageBean;
import com.woniu.entity.Role;
import com.woniu.exception.controllerException.ControllerException;
import com.woniu.mapper.RoleMapper;
import com.woniu.mapper.RoleMidAuthMapper;
import com.woniu.mapper.RoleMidMenuMapper;
import com.woniu.service.IRoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author hyl
 * @since 2022-08-28
 */
@Service
@Slf4j
@Transactional
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {


    @Autowired
    private RoleMidAuthMapper roleMidAuthMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleMidMenuMapper roleMidMenuMapper;

    /**
     * 添加角色信息
     * <p>添加角色信息时，应同时为其分配权限与菜单信息</p>
     * <p>因此，应同时添加该角色的权限列表 accessItem 和菜单列表 menuItem </p>
     * <p>将会根据传入的 accessIds 数组 和 menuIds 数组，一一添加该角色的权限明细和菜单明细到对应的明细表中</p>
     *
     * @param role      封装了待添加的角色的 Role 实例
     * @param authIds 为该角色分配的权限的id数组
     * @param menuIds   为该角色分配的菜单的id数组
     * @throws ControllerException 如果mybatis出现异常，会抛出该异常
     */
    @Override
    public void add(Role role, int[] authIds, int[] menuIds) throws ControllerException {

        if (roleMapper.getByName(role.getRoleName()) > 0) {
            throw new ControllerException("角色名已存在 : " + role.getRoleName());
        }

        roleMapper.insert(role);

        int roleId = role.getRoleId();
        log.debug("roleId:{}", roleId);


        addAccessesAndMenus(roleId, authIds, menuIds);
    }

    /**
     * 添加权限明细和菜单明细
     *
     * @param authIds 权限id数组
     * @param menuIds   菜单id数组
     * @param roleId    角色id
     */
    private void addAccessesAndMenus(int roleId, int[] authIds, int[] menuIds) {
        for (int authId : authIds) {
            roleMidAuthMapper.insert(roleId, authId);
        }

        for (int menuId : menuIds) {
            roleMidMenuMapper.insert(roleId, menuId);
        }
    }


    public void delete(int roleId) {
        roleMapper.delete(roleId);
    }


    /**
     * 修改角色信息
     *
     * @param role      封装了角色信息的Role实例
     * @param authIds 修改后的权限id数组
     * @param menuIds   修改后的菜单id数组
     * @throws ControllerException 如果mybatis出现异常，会抛出该异常
     */
    @Override
    public void update(Role role, int[] authIds, int[] menuIds) throws ControllerException {

        roleMapper.update(role);
        if (roleMapper.getByName(role.getRoleName()) > 0) {
            throw new ControllerException("角色名已存在 : " + role.getRoleName());
        }

        int roleId = role.getRoleId();
        roleMidAuthMapper.deleteAccessesByRoleId(roleId);
        roleMidMenuMapper.deleteMenusByRoleId(roleId);
        addAccessesAndMenus(roleId, authIds, menuIds);


    }

    @Override
    public int getByName(String name) {
        return roleMapper.getByName(name);
    }


    /**
     * 根据指定id查询角色信息
     *
     * @param roleId 角色的id
     * @return 根据 id 查询到的角色信息
     */
    @Override
    public Role getById(int roleId) {
        Role role;

        role = roleMapper.getById(roleId);

        return role;
    }


    /**
     * 多条件查询角色
     *
     * @param role 封装了角色信息的 Role 实例
     * @return 查询得到的 Role 集合
     */
    @Override
    public PageBean<Role> getByPage(Role role, int pageNum, int pageSize) {
        PageBean<Role> pageBean = new PageBean<>();
        Page<Object> page = PageHelper.startPage(pageNum, pageSize);
        List<Role> roles = roleMapper.getByCondition(role);

        pageBean.setCurrPage(pageNum);
        pageBean.setData(roles);
        pageBean.setCurrPageSize(roles.size());
        pageBean.setPageSize(pageSize);
        pageBean.setTotalPages(page.getPages());
        pageBean.setTotalNums((int) page.getTotal());

        return pageBean;
    }

    @Override
    public List<Role> getAll() {
        return roleMapper.getByCondition(new Role());
    }
}
